package pacBioSimple;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class PacBioLinkerMerger {

	String fileNamePacBioFasta = null;
	String fileNameBLASTResult = null;
	String fileNameOutput = null;
	Map<String,List<PacBioBlastHitObject> > blastHits = null;
	int maxLinkerLength=46;
	
	public PacBioLinkerMerger(String fileNamePacBio, String filenameBLASTResult,String output) {
		this.fileNameBLASTResult = filenameBLASTResult;
		this.fileNamePacBioFasta = fileNamePacBio;
		this.fileNameOutput = output;
	}
	
	
	public void readBlastR()
	{		
		try(BufferedReader blastResult = new BufferedReader(new FileReader(new File(fileNameBLASTResult))))
		{
			this.blastHits = new HashMap<>();
			String delim = "[ \t]";
			
			PacBioBlastHitObject prevBlastentry = null;
						
			List<PacBioBlastHitObject> blastHit = new ArrayList<>();
			
			while(blastResult.ready())
			{
				String[] blastToken = blastResult.readLine().split(delim);
				if(prevBlastentry== null)
				{
					prevBlastentry = new PacBioBlastHitObject(blastToken);
				}
				else
				{
					PacBioBlastHitObject current = new PacBioBlastHitObject(blastToken);
					if(PacBioBlastHitObject.isIntersect(prevBlastentry, current)) //check if both are intersecting or not
					{
						//update prev
						prevBlastentry=PacBioBlastHitObject.mergeObject(prevBlastentry, current);
					}
					else
					{
						if(prevBlastentry.getName().equals(current.getName())) //no intersection maybe the name is the same!
						{
							blastHit.add(prevBlastentry);	
						}
						else // no intersection different name 
						{
							//now we have to go through pacBiofasta, find the sequence and
							blastHit.add(prevBlastentry);
							this.blastHits.put(prevBlastentry.getName(), blastHit);
							//do magic here			
							blastHit = new ArrayList<>();
						}
						prevBlastentry = current;
					}
				}				
			}
			blastResult.close();
			blastHit.add(prevBlastentry);
			this.blastHits.put(prevBlastentry.getName(), blastHit);			
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	
	private List<String> cutFastaString(List<PacBioBlastHitObject> cutSides,String seq)
	{
		int oldB=0;
		List<String >results = new ArrayList<>();
		
		for(int i=0; i < cutSides.size();++i)
		{
			int cutB = cutSides.get(i).getBegin_q()-cutSides.get(i).getBegin_d();
			int cutE =cutSides.get(i).getEnd_q()+cutSides.get(i).getEnd_d();
//			int lengthString = seq.length();
			if(cutB+1> oldB)
			{
				results.add(seq.substring(oldB,cutB+1));	
			}
			oldB = cutE;
		}
		if(oldB<= seq.length()-1)
		{
			results.add(seq.substring(oldB,seq.length()));
		}		
		return results;
	}
	
	
	public void readPacBioFasta()
	{
		try(BufferedReader pacBioReader = new BufferedReader( new FileReader(new File(fileNamePacBioFasta))); 
				PrintWriter pwNoHit = new PrintWriter(new BufferedWriter(new FileWriter(fileNameOutput+"_noHit")));
				PrintWriter pwHit = new PrintWriter(new BufferedWriter(new FileWriter(fileNameOutput+"_Hit")))) {
			
			while(pacBioReader.ready())
			{
				String token = pacBioReader.readLine();
				if(token.charAt(0) == '>')
				{
					//check if we have the right name
					if(this.blastHits.containsKey(token.substring(1)))
					{
						//WE HAVE A HIT!!!
						//pwHit.println(token);
						
						List<String> results = cutFastaString(this.blastHits.get(token.substring(1)),pacBioReader.readLine());
						for(int i=0; i< results.size();++i)
						{
							if(results.get(i).length()>50)
							{
								if(i==0)
								{
									pwHit.println(token);
								}
								pwHit.println(results.get(i));
							}
						}						
					}
					else
					{
						pwNoHit.println(token);
					}					
				}
				else
				{
					pwNoHit.println(token);
				}
			}
			pwHit.flush();
			pwNoHit.flush();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
}
